package com.scalar.chiptrack.adaptor.utac;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.chiptrack.utils.DateUtil;
import com.scalar.chiptrack.users.VendorAdaptor;
import com.scalar.chiptrack.users.dao.AdaptorSetUpDAO;
import com.scalar.ScalarException;

import java.io.BufferedInputStream;
import java.io.InputStreamReader;
import java.util.Calendar;
import java.net.URL;

import HTTPClient.HTTPConnection;
import HTTPClient.HTTPResponse;
import HTTPClient.CookieModule;
import HTTPClient.NVPair;
import Acme.HtmlScanner;

/**
 * User: ChandraSekhar
 * Date: May 16, 2007
 * Time: 10:40:36 AM
 */
public class UTACAdaptor extends JobHandler implements AdaptorConstants
{
    private static final String PROTOCOL_HTTP           = "http";
    private static final String HOST                    = "webportal.utac.com.sg";
    private static final String GET_PORTAL              = "/Customer/gf_left_panel.asp";
    private static final String POST_LOGIN_URL          = "/Customer/gf_login.asp";
    private static final String GET_WIP_STATUS          = "/Customer/rt_criteria_sel.asp?lngRptID=2";
    private static final String GENERATE_WIP_REPORT     = "/Customer/rt_criteria_sel.asp";
    private static final String LOG_OUT                 = "/Customer/gf_logout.asp";
    private static final int DEFAULT_PORT               = 80;

    public static final String FILE_NAME_SHIP_STATUS    = "UTAC_SHIP_STATUS";
    public static final String FILE_NAME_WIP_STATUS     = "UTAC_WIP_STATUS";
    public static final String ADAPTOR_NAME             = "UTAC_ASSEMBLY";

    private String m_dataOutputDir      = null;
    private Logger m_adaptorLogger      = null;
    private String m_username           = null;
    private String m_password           = null;
    private static URL s_dummyUrl       = null;
    private int    m_adaptor_id     = -1;
    
    /**
     * - Called by HTML Scanner whenever it reads HTML pages
     * - Keeps track of required URLs
     */
    private UTACHtmlObserver m_observer = null;

    public UTACAdaptor() throws Exception
    {
        if (s_dummyUrl == null)
        {
            try
            {
                s_dummyUrl = new URL("http://" + HOST );
            }
            catch (Exception ignore) {
            }
        }

        try
        {
            VendorAdaptor vendorAdaptor = AdaptorSetUpDAO.getVendorAdaptorDetailsByVendorNameAndLocation( VENDOR_NAME_UTAC, LOCATION_TYPE_ASSEMBLY );

            if( vendorAdaptor == null )
            {
                log( "ERROR!! ERROR!! ERROR!! Exception while loading UTAC Adaptor Username, Password details from database" );
                throw new ScalarException( "Exception while loading UTAC Adaptor Username, Password details from database" );
            }

            m_username = vendorAdaptor.getUserId().trim();
            m_password = vendorAdaptor.getPassWord().trim();
            m_dataOutputDir = vendorAdaptor.getOutPutDirectory().trim();

            if ( m_dataOutputDir != null )
            {
                if ( m_dataOutputDir.endsWith( "/" ) || m_dataOutputDir.endsWith( "\\" ) )
                {
                    m_dataOutputDir = m_dataOutputDir + m_username;
                }
                else
                {
                    m_dataOutputDir = m_dataOutputDir + "/" + m_username;
                }

                AdaptorUtils.makeAllAdaptorDirs( m_dataOutputDir );
                m_adaptorLogger = AdaptorUtils.getAdaptorLogger( m_dataOutputDir, VENDOR_NAME_UTAC );
                AdaptorUtils.setLogger( m_adaptorLogger );
            }
        }
        catch ( Exception se )
        {
            log( "ERROR!! ERROR!! ERROR!! Exception while loading UTAC Adaptor Username, Password details from database, Exception: " + se );
            throw new ScalarException( "Exception while loading UTAC Adaptor Username, Password details from database" );
        }

        m_observer = new UTACHtmlObserver();
    }

    public static void main( String[] args ) throws Exception
    {
        new UTACAdaptor().execute();
    }

    public void execute() throws Exception
    {
        try
        {
            m_adaptor_id = AdaptorRunInfo.saveAdaptorLastUpdatedStatus( CONSTANT_ADAPTOR, ADAPTOR_NAME, CONSTANT_SUCCESS, -1);

            AdaptorUtils.printHeader(VENDOR_NAME_UTAC, CONSTANT_ADAPTOR);

            AdaptorUtils.removeOldFiles(m_dataOutputDir, m_adaptorLogger);

            HTTPConnection connection = login( HOST, DEFAULT_PORT, m_username, m_password );

            if ( connection != null )
            {
                BufferedInputStream bfReader = null;

                //For DownLoading WipStatus Report
                HTTPResponse rsp = requestWipStatusReport( connection );

                if( rsp != null )
                {
                    bfReader = new BufferedInputStream( rsp.getInputStream()  );
                    if( bfReader != null )
                    {
                        System.out.println( "\tDownloading the Wip Status Sheet..." );
                        log( "\tDownloading the Wip Status Sheet..." );
                        AdaptorUtils.saveAsBinaryFile( bfReader, m_dataOutputDir, FILE_NAME_WIP_STATUS, FILE_EXTN_CSV,true );
                        if (m_adaptor_id > 0 )
                        {
                            AdaptorRunInfo.saveAdaptorFileInfo( m_adaptor_id , FILE_NAME_WIP_STATUS, FILE_EXTN_CSV, StringUtils.formatDateandTime(DateUtil.getFormattedTimeStamp() )) ;
                        }
                    }
                    else
                    {
                        log( "Could not save Lot Status Sheet from Buffer Reader" );
                        throw new ScalarException( "Could not save Wip Status Sheet from Buffer Reader" );
                    }
                }
                else
                {
                    log( "Could not create response object of Wip Status Sheet" );
                    throw new ScalarException( "Could not create response object of Wip Status Sheet" );
                }

                // For DownLoding the Shipment Information
                /*rsp = requestDynamicShippingReport( connection );

                if( rsp != null )
                {
                    bfReader = new BufferedInputStream( rsp.getInputStream()  );
                    if( bfReader != null )
                    {
                        System.out.println( "\tDownloading the Shipment info Sheet..." );
                        log( "\tDownloading the Shipment info Sheet..." );
                        AdaptorUtils.saveAsBinaryFile( bfReader, m_dataOutputDir, FILE_NAME_SHIP_STATUS, AdaptorUtils.FILE_EXTN_HTML,true );
                    }
                    else
                    {
                        log( "Could not save Dynamic Ship Status Sheet from Buffer Reader" );
                        throw new ScalarException( "Could not save Ship Status Sheet from Buffer Reader" );
                    }
                }
                else
                {
                    log( "Could not create response object of Ship Status Sheet" );
                    throw new ScalarException( "Could not create response object of Ship Status Sheet" );
                }
                 */
                
                // Logging out from UTAC WEB SITE
                logout( connection );
                bfReader = null;
            }
            else
            {
                log( "Could not able to get the Connection to web site" );
                throw new ScalarException( "Could not able to get the Connection to web site" );
            }
        }
        catch(Exception e)
        {
            AdaptorUtils.removeOldFiles(m_dataOutputDir, m_adaptorLogger);
            AdaptorRunInfo.updatedAdaptorStatus( CONSTANT_FAILURE, m_adaptor_id);
            System.out.println("Exception while trying to connect and read data from " + HOST +" site: " + e);
            log("Exception while trying to connect and read data from " + HOST +" site: " + e);
            e.printStackTrace();
            throw e;
        }
    }

    private HTTPConnection login( String host, int port, String username, String password ) throws Exception
    {
        byte[] data         = new byte[1024];
        HTTPResponse    rsp = null;

        HTTPConnection conn = new HTTPConnection( PROTOCOL_HTTP, host, port );
        CookieModule.setCookiePolicyHandler( null );
        HTTPConnection.addDefaultModule( CookieModule.class, -1 );

        NVPair defaultHeaders[] = new NVPair[ 8 ];
        defaultHeaders[ 0 ] = new NVPair( "Accept", "*/*" );
        defaultHeaders[ 1 ] = new NVPair( "Referer", "http://" + host );
        defaultHeaders[ 2 ] = new NVPair( "Accept-Language", "en-us" );
        defaultHeaders[ 3 ] = new NVPair( "Content-Type", "application/x-www-form-urlencoded" );
        defaultHeaders[ 4 ] = new NVPair( "Proxy-Connection", "Keep-Alive" );
        defaultHeaders[ 5 ] = new NVPair( "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)" );
        defaultHeaders[ 6 ] = new NVPair( "Host", host );
        defaultHeaders[ 7 ] = new NVPair( "Pragma", "no-cache" );

        conn.setDefaultHeaders( defaultHeaders );

        rsp  = conn.Get( GET_PORTAL );

        NVPair[] formData = new NVPair[ 3 ];
        formData[ 0 ] = new NVPair( "strUserNm", username );
        formData[ 1 ] = new NVPair( "strPassword", password );
        formData[ 2 ] = new NVPair( "login", "Login");

        System.out.print( "Trying to Logging in......" );
        log( "Trying to Logging in......" );

        rsp  = conn.Post( POST_LOGIN_URL, formData );

        /*while ( rsp.getInputStream().read( data ) != -1 )
        {
        	log( new String( data ) );
        }*/

        log( "Response from Server: " + rsp.getStatusCode() + " " + rsp.getReasonLine() );

        if ( rsp.getStatusCode() >= 400 )
        {
            System.out.println( "\nLogin failed.. response from server: " + rsp.getStatusCode() );
            log( "\nLogin failed.. response from server: " + rsp.getStatusCode() );
            conn = null;
        }

        log( "Done." );
        return conn;
    }

    private HTTPResponse requestWipStatusReport( HTTPConnection conn) throws Exception
    {
        byte[] data         = new byte[1024*2];
        HTTPResponse rsp    = null;

        System.out.println( "\t\nSubmitting the request for Wip Staus......" );
        log( "\tSubmitting the request for Wip Staus......" );

        rsp = conn.Get( GET_WIP_STATUS );

        UTACHtmlParser parser = new UTACHtmlParser();

        parser.parse( new InputStreamReader( rsp.getInputStream() ) );


        String year     = parser.getYear();
        String actMonth = parser.getMonth();
        String day      = parser.getDay();
        String hour     = parser.getHour();

        /*while ( rsp.getInputStream().read( data ) != -1 )
        {
            log(new String(data));
        }*/

        String timeStampParam = year+actMonth+day+hour+"0000^"+actMonth+"/"+day+"/"+year+" "+hour+":00:00";

        NVPair[] formData = new NVPair[ 44 ];
              
        formData[ 0 ] = new NVPair( "TIMESTAMP",  timeStampParam );
        formData[ 1 ] = new NVPair( "strFieldAlias", "TIMESTAMP" );
        formData[ 2 ] = new NVPair( "strFieldNm", "TIMESTAMP" );
        formData[ 3 ] = new NVPair( "strOperator", "=" );
        formData[ 4 ] = new NVPair( "strDataType", "VARCHAR" );
        formData[ 5 ] = new NVPair( "TIMESTAMP_mth", actMonth);
        formData[ 6 ] = new NVPair( "TIMESTAMP_day", day);
        formData[ 7 ] = new NVPair( "TIMESTAMP_year", year );
        formData[ 8 ] = new NVPair( "TIMESTAMP_hour", hour);
        formData[ 9 ] = new NVPair( "TIMESTAMP_min", "00");
        formData[ 10 ] = new NVPair( "TIMESTAMP_sec", "00");
        // Supplier ID
        formData[ 11 ] = new NVPair( "strFieldNm", "SUPPLIERID");
        formData[ 12 ] = new NVPair( "strOperator", "=");
        formData[ 13 ] = new NVPair( "strFieldAlias", "SUPPLIERID");
        formData[ 14 ] = new NVPair( "strDataType", "VARCHAR");
        formData[ 15 ] = new NVPair( "SUPPLIERID", "AN1 ^ ANALOGIX");
        //Lot ID / Customer Lot ID
        formData[ 16 ] = new NVPair( "strLotOption", "LOTID");
        formData[ 17 ] = new NVPair( "strFieldAlias", "LOTID");
        formData[ 18 ] = new NVPair( "strFieldNm", "LOTID");
        formData[ 19 ] = new NVPair( "strOperator", "LIKE");
        formData[ 20 ] = new NVPair( "strDataType", "VARCHAR");
        formData[ 21 ] = new NVPair( "strPrevLotValue", "");
        formData[ 22 ] = new NVPair( "LOTID", "");
        //Part ID / Customer Part In / Customer Part Out
        formData[ 23 ] = new NVPair( "strPartOption", "PARTID");
        formData[ 24 ] = new NVPair( "strFieldAlias", "PARTID");
        formData[ 25 ] = new NVPair( "strFieldNm", "PARTID");
        formData[ 26 ] = new NVPair( "strOperator", "LIKE");
        formData[ 27 ] = new NVPair( "strDataType", "VARCHAR");
        formData[ 28 ] = new NVPair( "strPrevPartValue", "");
        formData[ 29 ] = new NVPair( "PARTID", "");
        //Lot Type
        formData[ 30 ] = new NVPair( "strFieldAlias", "LOTTYPE");
        formData[ 31 ] = new NVPair( "strFieldNm", "LOTTYPE");
        formData[ 32 ] = new NVPair( "strOperator", "=");
        formData[ 33 ] = new NVPair( "strDataType", "VARCHAR");
        formData[ 34 ] = new NVPair( "LOTTYPE", "All");

        formData[ 35 ] = new NVPair( "DERIVED_STGYLD", "");
        formData[ 36 ] = new NVPair( "CYCLETIME", "");
        
        formData[ 37 ] = new NVPair( "lngRptID", "2");
        formData[ 38 ] = new NVPair( "strRptType", "H");
        formData[ 39 ] = new NVPair( "strRptNm", "WIP");
        formData[ 40 ] = new NVPair( "strViewNm", "vw_wip");
        //Report Action Type
        formData[ 41 ] = new NVPair( "strActionType", "GenRpt");
        
        formData[ 42 ] = new NVPair( "strDateType", "TIMESTAMP");
        
        rsp = conn.Post( GENERATE_WIP_REPORT, formData );
       
        /*while ( rsp.getInputStream().read( data ) != -1 )
        {
            log(new String(data));
        }*/
        HtmlScanner htmlScanner = new HtmlScanner( rsp.getInputStream(), s_dummyUrl, m_observer );
        while (htmlScanner.read(data) != -1)
        {
        }

        rsp = conn.Get( m_observer.getDownLoadCsvURL() );

        return rsp;
    }


    private HTTPResponse requestDynamicShippingReport( HTTPConnection conn) throws Exception
    {
        byte[] data         = new byte[1024];
        HTTPResponse rsp = null;

        //rsp = conn.Get( "/portal" );


        /*while ( rsp.getInputStream().read( data ) != -1 )
        {
            //log( new String( data ) );
        }*/
        System.out.println( "\tSubmitting the request for Shipping Info......" );
        log( "\tSubmitting the request for Shipping Info......" );

        /*while ( rsp.getInputStream().read( data ) != -1 )
        {
            log(new String(data));
        }*/

        return rsp;
    }

    private void logout( HTTPConnection conn ) throws Exception
    {
        try
        {
            System.out.print( "\n Logging out... " );
            log( "\n Logging out... " );
            HTTPResponse rsp = conn.Get( LOG_OUT );
            System.out.println( "Successfully logged out from UTAC Site" );
            log( "Successfully logged out from UTAC Site" );

            conn = null;
            rsp = null;
        }
        catch ( Exception ignore )
        {
            System.out.println( "Exception Occuered While Logging Out From UTAC Site" + ignore);
            throw ignore;
        }
    }

    private void log( String message )
    {
        if ( message == null ) return;

        if ( m_adaptorLogger != null )
        {
            synchronized ( m_adaptorLogger )
            {
                m_adaptorLogger.logDebug( message + LINE_SEPARATOR );
            }
        }
        else
        {
            System.out.println( message );
        }
    }
}
